//package ameba.lib;
//
//import ameba.websocket.WebSocketException;
//import org.glassfish.jersey.internal.util.Producer;
//import org.glassfish.jersey.process.internal.RequestScope;
//
//import java.lang.invoke.MethodHandle;
//import java.lang.invoke.MethodHandles;
//import java.lang.reflect.Field;
//import java.security.PrivilegedAction;
//import java.util.concurrent.Callable;
//
//import static java.lang.invoke.MethodType.methodType;
//
///**
// * <p>JerseyScopeDelegate class.</p>
// *
// * @author icode
// *
// */
//public class JerseyScopeDelegate {
//    private static final MethodHandles.Lookup lookup = ((PrivilegedAction<MethodHandles.Lookup>) () -> {
//        try {
//            Field field = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
//            field.setAccessible(true);
//            return (MethodHandles.Lookup) field.get(null);
//        } catch (NoSuchFieldException | IllegalAccessException e) {
//            throw new WebSocketException(e);
//        }
//    }).run();
//    private static final MethodHandle RETRIEVE_CURRENT_HANDLE = getMethodHandle(
//            "retrieveCurrent",
//            RequestScope.Instance.class
//    );
//    private static final MethodHandle SET_CURRENT_HANDLE = getMethodHandle(
//            "setCurrent",
//            void.class,
//            RequestScope.Instance.class
//    );
//    private static final MethodHandle RESUME_CURRENT_HANDLE = getMethodHandle(
//            "resumeCurrent",
//            void.class,
//            RequestScope.Instance.class
//    );
//    private RequestScope scope;
//
//
//    /**
//     * <p>Constructor for JerseyScopeDelegate.</p>
//     *
//     * @param scope a {@link org.glassfish.jersey.process.internal.RequestScope} object.
//     */
//    public JerseyScopeDelegate(RequestScope scope) {
//        this.scope = scope;
//    }
//
//    private static MethodHandle getMethodHandle(String name, Class rtype, Class... args) {
//        try {
//            return lookup.findSpecial(
//                    RequestScope.class,
//                    name,
//                    methodType(rtype, args),
//                    RequestScope.class
//            );
//        } catch (NoSuchMethodException | IllegalAccessException e) {
//            throw new WebSocketException(e);
//        }
//    }
//
//    /**
//     * <p>createInstance.</p>
//     *
//     * @return a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     */
//    public RequestScope.Instance createInstance() {
//        return scope.createInstance();
//    }
//
//    /**
//     * <p>retrieveCurrent.</p>
//     *
//     * @return a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     */
//    public RequestScope.Instance retrieveCurrent() {
//        try {
//            return (RequestScope.Instance) RETRIEVE_CURRENT_HANDLE.invokeExact(this.scope);
//        } catch (Throwable throwable) {
//            throw new WebSocketException(throwable);
//        }
//    }
//
//    /**
//     * <p>setCurrent.</p>
//     *
//     * @param instance a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     */
//    public void setCurrent(RequestScope.Instance instance) {
//        try {
//            SET_CURRENT_HANDLE.invokeExact(this.scope, instance);
//        } catch (Throwable throwable) {
//            throw new WebSocketException(throwable);
//        }
//    }
//
//    /**
//     * <p>resumeCurrent.</p>
//     *
//     * @param oldInstance a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     */
//    public void resumeCurrent(RequestScope.Instance oldInstance) {
//        try {
//            RESUME_CURRENT_HANDLE.invokeExact(this.scope, oldInstance);
//        } catch (Throwable throwable) {
//            throw new WebSocketException(throwable);
//        }
//    }
//
//    /**
//     * <p>isActive.</p>
//     *
//     * @return a boolean.
//     */
//    public boolean isActive() {
//        return scope.isActive();
//    }
//
//    /**
//     * <p>referenceCurrent.</p>
//     *
//     * @return a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     * @throws java.lang.IllegalStateException if any.
//     */
//    public RequestScope.Instance referenceCurrent() throws IllegalStateException {
//        return scope.referenceCurrent();
//    }
//
//    public RequestScope.Instance current() {
//        return scope.current();
//    }
//
//    /**
//     * <p>suspendCurrent.</p>
//     *
//     * @return a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     */
//    public RequestScope.Instance suspendCurrent() {
//        return scope.suspendCurrent();
//    }
//
//    /**
//     * <p>runInScope.</p>
//     *
//     * @param scopeInstance a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     * @param task a {@link java.lang.Runnable} object.
//     */
//    public void runInScope(RequestScope.Instance scopeInstance, Runnable task) {
//        scope.runInScope(scopeInstance, task);
//    }
//
//    /**
//     * <p>runInScope.</p>
//     *
//     * @param task a {@link java.lang.Runnable} object.
//     */
//    public void runInScope(Runnable task) {
//        scope.runInScope(task);
//    }
//
//    /**
//     * <p>runInScope.</p>
//     *
//     * @param scopeInstance a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     * @param task a {@link java.util.concurrent.Callable} object.
//     * @param <T> a T object.
//     * @return a T object.
//     * @throws java.lang.Exception if any.
//     */
//    public <T> T runInScope(RequestScope.Instance scopeInstance, Callable<T> task) throws Exception {
//        return scope.runInScope(scopeInstance, task);
//    }
//
//    /**
//     * <p>runInScope.</p>
//     *
//     * @param task a {@link java.util.concurrent.Callable} object.
//     * @param <T> a T object.
//     * @return a T object.
//     * @throws java.lang.Exception if any.
//     */
//    public <T> T runInScope(Callable<T> task) throws Exception {
//        return scope.runInScope(task);
//    }
//
//    /**
//     * <p>runInScope.</p>
//     *
//     * @param scopeInstance a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     * @param task a {@link org.glassfish.jersey.internal.util.Producer} object.
//     * @param <T> a T object.
//     * @return a T object.
//     */
//    public <T> T runInScope(RequestScope.Instance scopeInstance, Producer<T> task) {
//        return scope.runInScope(scopeInstance, task);
//    }
//
//    /**
//     * <p>runInScope.</p>
//     *
//     * @param task a {@link org.glassfish.jersey.internal.util.Producer} object.
//     * @param <T> a T object.
//     * @return a T object.
//     */
//    public <T> T runInScope(Producer<T> task) {
//        return scope.runInScope(task);
//    }
//
//    /**
//     * <p>enterScope.</p>
//     *
//     * @return a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     */
//    public RequestScope.Instance enterScope() {
//        final RequestScope.Instance oldInstance = retrieveCurrent();
//        final RequestScope.Instance instance = createInstance();
//        setCurrent(instance);
//        return oldInstance;
//    }
//
//    /**
//     * <p>leaveScope.</p>
//     *
//     * @param oldInstance a {@link org.glassfish.jersey.process.internal.RequestScope.Instance} object.
//     */
//    public void leaveScope(RequestScope.Instance oldInstance) {
//        retrieveCurrent().release();
//        resumeCurrent(oldInstance);
//    }
//
//    /**
//     * <p>shutdown.</p>
//     */
//    public void shutdown() {
//        scope.shutdown();
//    }
//}
